import 'package:flutter/foundation.dart';

import 'XaBleManager.dart';
import 'ble_log.dart';
import 'ble_utils.dart';

class XABleRequest {
  final String deviceId;
  final String cmd;
  final String data;

  const XABleRequest({
    this.data = '',
    this.cmd,
    this.deviceId,
  });

  @override
  String toString() {
    String content = '6850$cmd$deviceId${getDataLength()}$data';
    String cs = BleUtils.makeChecksum(content).toString().toUpperCase();
    return '$content${cs}16';
  }

  String getDataLength() {
    if (data == null || data.isEmpty) return '00';
    String l = (data.length ~/ 2).toRadixString(16);
    if (l.length == 1) {
      l = '0$l';
    }
    return l;
  }
}

class XABleResponse {
  static String checkNullToString(value) {
    return value != null ? value.toString() : '';
  }

  factory XABleResponse.fromContent(String json) {
    String cmd = json.substring(4, 6);
    String deviceId = json.substring(6, 22);
    String data = json.substring(24, json.length - 4);
    return XABleResponse(
        data: data, deviceId: deviceId, cmd: cmd, resContent: json, code: '00');
  }

  String data = '';
  String cmd = '';
  String deviceId = '';
  String resContent = '';
  String code = '';
  String error = '';

  XABleResponse({
    this.data,
    this.deviceId,
    this.cmd,
    this.resContent,
    this.code,
    this.error,
  });

  String get uuid => data;

  String get randomKey => data.substring(6, 8);

  String get dataToSend => data.substring(8, data.length);

  @override
  String toString() {
    return "BleRes: cmd $cmd \r\ndata:$resContent";
  }
}

class XAServiceRequestModel {
  ///设备标识 32
  final String uuid;

  ///业务类型 2
  final String reqType;

  ///数据域 长度不固定
  final String data;

  ///应用标识 2
  final String appCode;

  ///密钥索引 2
  final String keyValue;

  factory XAServiceRequestModel.fromBleRes(String uuid, XABleResponse bleRes,
      {String reqType = '10'}) {
    return XAServiceRequestModel(
      uuid: uuid,
      reqType: reqType,
      data: bleRes.dataToSend,
      keyValue: bleRes.randomKey,
    );
  }

  factory XAServiceRequestModel.decryptReq(
      String uuid, String randomKey, String data) {
    return XAServiceRequestModel(
      uuid: uuid,
      reqType: '40',
      data: data,
      keyValue: randomKey,
    );
  }

  const XAServiceRequestModel({
    @required this.uuid,
    @required this.reqType,
    this.data = '',
    this.appCode = XaBleManager.appCode,
    this.keyValue = '00',
  });

  @override
  String toString() {
    String content = '$appCode$reqType$keyValue$uuid$data';
    int length = content.length + 4;
    return '@@${convertIntToString(length)}$content@!!@';
  }

  String convertIntToString(int length) {
    String temp = length.toString();
    if (temp.length == 1) return '000$temp';
    if (temp.length == 2) return '00$temp';
    if (temp.length == 3) return '0$temp';
    return temp;
  }
}

class XAServiceResponseModel {
  ///数据域 长度不固定
  final String data;

  ///校验域 4
  final String textEnd;

  ///状态 2
  final String status;

  final String socketContent;

  XAServiceResponseModel({
    this.data,
    this.textEnd,
    this.status,
    this.socketContent,
  });

  factory XAServiceResponseModel.fromSocket(String data) {
    String temp = data.substring(6, data.length - 4);
    String code = temp.substring(0, 2);
    String textEnd = temp.substring(temp.length - 4, temp.length);
    String content = temp.substring(2, temp.length - 4);
    LogUtils.debug('code :$code');
    LogUtils.debug('数据域: $content');
    LogUtils.debug('校验域: $textEnd');
    return XAServiceResponseModel(
        data: content, textEnd: textEnd, status: code, socketContent: data);
  }

  @override
  String toString() {
    return 'socketRes: $socketContent';
  }
}

class WriteCardContentModel {
  //卡号
  final String cardNo;

  //卡备注
  final String cardMemo;

  //发卡次数
  final String cardNumber;

  //购气量
  final String buyGas;

  //购气次数
  final String buyTime;

  //累计购气量
  final String totalBuyGas;

  const WriteCardContentModel(
      {this.cardNumber,
      this.cardNo,
      this.cardMemo,
      this.buyGas,
      this.buyTime,
      this.totalBuyGas});

  @override
  String toString() {
    return '${cardNo}FF$cardMemo$cardNumber$buyGas$buyTime$totalBuyGas';
  }

  factory WriteCardContentModel.cardModel(
      {int buyTime,
      int buyGas,
      int totalBuyGas,
      ReadCardContentModel readCardModel}) {
    return WriteCardContentModel(
      cardNo: readCardModel.cardNo,
      cardNumber: readCardModel.cardNumber,
      cardMemo: readCardModel.cardMemo,
      buyGas: convertGasToString(buyGas),
      buyTime: convertBuyTimeToString(buyTime),
      totalBuyGas: convertTotalBuyGasToString(buyTime),
    );
  }

  static String convertTotalBuyGasToString(int length) {
    String temp = length.toString();
    if (temp.length == 1) return '00000$temp';
    if (temp.length == 2) return '0000$temp';
    if (temp.length == 3) return '000$temp';
    if (temp.length == 4) return '00$temp';
    if (temp.length == 5) return '0$temp';
    if (temp.length == 6) return '$temp';
    return temp;
  }

  static String convertBuyTimeToString(int length) {
    String temp = length.toString();
    if (temp.length == 1) return '000$temp';
    if (temp.length == 2) return '000$temp';
    if (temp.length == 3) return '0$temp';
    if (temp.length == 4) return '$temp';
    return temp;
  }

  static String convertGasToString(int length) {
    String temp = length.toString();
    if (temp.length == 1) return '0000000$temp';
    if (temp.length == 2) return '000000$temp';
    if (temp.length == 3) return '00000$temp';
    if (temp.length == 4) return '0000$temp';
    if (temp.length == 5) return '000$temp';
    if (temp.length == 6) return '00$temp';
    if (temp.length == 7) return '0$temp';
    if (temp.length == 8) return '$temp';
    return temp;
  }
}

class ReadCardContentModel {
  //卡号
  final String cardNo;

  //卡备注
  final String cardMemo;

  //发卡次数
  final String cardNumber;

  //卡内气量
  final String cardGas;

  //表内气量
  final String meterGas;

  //累计用量
  final String totalGas;

  //购气次数
  final String buyNumber;

  const ReadCardContentModel({
    this.cardMemo,
    this.cardNo,
    this.cardGas,
    this.cardNumber,
    this.meterGas,
    this.totalGas,
    this.buyNumber,
  });

  factory ReadCardContentModel.fromContent(String e) {
    return ReadCardContentModel(
      cardNo: e.substring(0, 8),
      cardMemo: e.substring(10, 12),
      cardNumber: e.substring(12, 14),
      cardGas: e.substring(14, 22),
      meterGas: e.substring(22, 30),
      totalGas: e.substring(30, 38),
      buyNumber: e.substring(40, 44),
    );
  }

  @override
  String toString() {
    return '卡号 :$cardNo\r\n卡备注 :$cardMemo\r\n发卡次数 :$cardNumber\r\n卡内气量 :$cardGas\r\n表内气量 :$meterGas\r\n累计用量 :$totalGas\r\n购气次数 :$buyNumber\r\n';
  }
}
